home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / dialgmgr.sit / Dialogs ƒ / Dialogs.p next >
Text File  |  1990-01-04  |  28KB  |  974 lines

  1. Unit TDialogs;
  2.  
  3. {        ⌐1986-1989            Bill Stackhouse                                    }
  4. {                                Stackhouse Software                                }
  5. {                                Natick, MA 01760                                }
  6.  
  7. Interface
  8.  
  9. {$IFC UNDEFINED UsePopUpMenu}
  10. {$SETC UsePopUpMenu = FALSE}
  11. {$ENDC}
  12.  
  13. {$IFC UNDEFINED UseRadioGroup}
  14. {$SETC UseRadioGroup = FALSE}
  15. {$ENDC}
  16.  
  17. {$IFC UNDEFINED UseTextGroup}
  18. {$SETC UseTextGroup = FALSE}
  19. {$ENDC}
  20.  
  21. {$IFC UNDEFINED UseKeyGroup}
  22. {$SETC UseKeyGroup = FALSE}
  23. {$ENDC}
  24.  
  25. {$IFC UNDEFINED UseUserItem}
  26. {$SETC UseUserItem = FALSE}
  27. {$ENDC}
  28.  
  29. {$IFC UNDEFINED UseListItem}
  30. {$SETC UseListItem = FALSE}
  31. {$ENDC}
  32.  
  33.     Uses
  34.         TObject, 
  35. {$IFC UsePopUpMenu}
  36.         TPopUpMenu, 
  37. {$ENDC}
  38. {$IFC UseRadioGroup}
  39.         TRadioGroup, 
  40. {$ENDC}
  41. {$IFC UseTextGroup}
  42.         TTextGroup, 
  43. {$ENDC}
  44. {$IFC UseKeyGroup}
  45.         TKeyGroup, 
  46. {$ENDC}
  47. {$IFC UseUserItem}
  48.         TUserItem, 
  49. {$ENDC}
  50. {$IFC UseListItem}
  51.         TListItem, 
  52. {$ENDC}
  53.         Centered;
  54.  
  55.     Const
  56.         DialogMaxItems = 255;
  57.         ReturnCode = 13;            {ASCII code generated by Return and Enter keys.  Note that}
  58.         EnterCode = 3;                {this is good for any keyboard, no matter how it's mapped}
  59.  
  60.                                     { Return Codes }
  61.         DialogNoErr = 0;                {all's well with the world}
  62.         DialogNotNumber = -1;        {Edit/Static text item did not have a number in it}
  63.         DialogInvalidOp = -2;        {Operation requested with support compiled out}
  64.         DialogInvalidItem = -3;        {item type invalid for op. eg. GetString on a radio control}
  65.         DialogGroupIgnored = -10;    {too many groups, key, menus, or user items were added}
  66.  
  67.     Type
  68.         DialogNumber = 0..DialogMaxItems;
  69.         DialogSet = Packed Set Of DialogNumber;
  70.  
  71.         TDialog = Object(TObject)
  72.                 fPrivate: Handle;
  73.  
  74. {    Init            - initialize internal data structures    }
  75. {    Define            - define basic information about dialog }
  76. {    Display        - show dialog }
  77. {    Accept        - process all event until button is pressed }
  78. {    Error            - returns error from last operation }
  79. {    Free            - take dialog window down and clean up internal data structures }
  80.                 Procedure TDialog.Init;
  81.                 Procedure TDialog.Define (pNumber: Integer;        {dialog number}
  82.                                             pChkDefault: DialogSet;                    {which check bopes default on}
  83.                                             pTextDefault: DialogNumber);            {which editText to put I-Beam}
  84.                 Procedure TDialog.Display (center: Boolean);
  85.                 Function TDialog.Accept: Integer;
  86.                 Function TDialog.Error: Integer;
  87.                 Procedure TDialog.Free;
  88.                 override;
  89.  
  90. {    RadioGroup        - define a group of related radio buttons which are exclusive of each other }
  91. {    RadioGroupGet    - find which button in the group is on }
  92. {    RadioGroupSet    - set a button in the group }
  93.                 Procedure TDialog.RadioGroup (pOn: DialogNumber;    {which is initially on}
  94.                                             pBtns: DialogSet;                            {which btns in a single group}
  95.                                             pTitle: String;                            {if length > 0, then title with box}
  96.                                             pTitleTop: Boolean);                        {TRUE - title on top, FALSE - title at left end}
  97.                 Procedure TDialog.RadioGroupGet (pGroup: Integer;
  98.                                             Var pItem: Integer);
  99.                 Procedure TDialog.RadioGroupSet (pGroup: Integer;
  100.                                             pItem: Integer);
  101.  
  102. {    TextGroup        - a check box / TextItem pair. When the check is on, the edit is selected}
  103.                 Procedure TDialog.TextGroup (pItem: DialogNumber;    {pairs of btn and edit text items}
  104.                                             pText: DialogNumber);                    {button item number}
  105.  
  106. {    PopMenu                - define a popup menu relative to a StaticText item }
  107. {    PopMenuGet            - find which menu item is currently on along with its' text }
  108. {    PopMenuCallBack    - user call back when popup used. No parms passed back since obj known }
  109.                 Procedure TDialog.PopMenu (pMenu: MenuHandle;    {nil or menu handle}
  110.                                             pMenuRes: Integer;                        {resource number}
  111.                                             pStatic: DialogNumber;                    {related StaticText item number}
  112.                                             pInitiallyOn: Integer);                        {menu item number initially on}
  113.                 Procedure TDialog.PopMenuGet (pGroup: Integer;        {group number}
  114.                                             Var pItem: Integer;                        {menu item number currently on}
  115.                                             Var pText: Str255);                        {menu item text currently on}
  116.                 Procedure TDialog.PopMenuCallBack (pCallBack: ProcPtr);    {proc addr}
  117.  
  118. {    UserItems        - define a user item }
  119.                 Procedure TDialog.UserItems (pItem: DialogNumber;    {user item number}
  120.                                             pDraw, pEvent, pSelect: ProcPtr;        {draw/event/select call backs}
  121.                                             pBox: Rect);                                {Rect that contains the item}
  122.  
  123. {    ItemList            - define a single column scrolable list }
  124. {    ItemListText        - add a single row to the list }
  125. {    ItemListGet        - find which item and its' text was last clicked }
  126.                 Procedure TDialog.ItemList (pItem: DialogNumber;        {item number}
  127.                                             pInitiallyOn: Integer;                        {item initially selected}
  128.                                             pShown: Integer);                            {max items to show}
  129.                 Procedure TDialog.ItemListText (pText: Str255);    {text single list item}
  130.                 Procedure TDialog.ItemListGet (pGroup: Integer;        {group number}
  131.                                             Var pItem: Integer;                        {list item number currently selected}
  132.                                             Var pText: Str255);                        {list item text currently selected}
  133.  
  134. {    KeyButton    - define keyboard equivalents }
  135.                 Procedure TDialog.KeyButton (pKey: char;        {command key}
  136.                                             pItem: DialogNumber);                    {button}
  137.  
  138. {    General utilities to set and retireve dialog item values }
  139.                 Function TDialog.GetBooleanValue (pItem: Integer): Boolean;
  140.                 Function TDialog.GetLongintValue (pItem: Integer): Longint;
  141.                 Function TDialog.GetStringValue (pItem: Integer): Str255;
  142.  
  143.                 Procedure TDialog.SetBooleanValue (pItem: Integer;
  144.                                             theValue: Boolean);
  145.                 Procedure TDialog.SetLongintValue (pItem: Integer;
  146.                                             theValue: Longint);
  147.                 Procedure TDialog.SetStringValue (pItem: Integer;
  148.                                             theValue: Str255;
  149.                                             forceFit: Boolean);
  150.  
  151. {    CenterText    - center the displayed text in the EditText }
  152. {    SelectText    - select the entire text in the EditText box }
  153.                 Procedure TDialog.CenterText (pItem: Integer);
  154.                 Procedure TDialog.SelectText (pItem: Integer);
  155.  
  156.             End;
  157.  
  158. Implementation
  159.  
  160.     Const
  161.         Off = 0;
  162.         On = 1;
  163.  
  164.         btnCtrlItem = 4;
  165.         chkCtrlItem = 5;
  166.         radCtrlItem = 6;
  167.         editCtrlItem = 16;
  168.  
  169.         maxGroups = 15;
  170.  
  171.     Type
  172.         TSearch = (searching, found, endList);
  173.  
  174.         HDialogInfo = ^PDialogInfo;
  175.         PDialogInfo = ^DialogInfo;
  176.         DialogInfo = Record
  177.                 number: Integer;                                {dialog resource number}
  178.                 curDialog: DialogPtr;                            {dialog pointer}
  179.                 numItems: DialogNumber;                    {number of items in dialog}
  180.                 btnDefault: Integer;                            {button when RETURN/ENTER hit}
  181.                 chkDefault: DialogSet;                        {which check boxes default on}
  182.                 textDefault: Integer;                            {which editText to put I-Beam}
  183. {$IFC UseUserItem}
  184.                 fUserItems: TUserItem;                        {}
  185. {$ENDC}
  186. {$IFC UseKeyGroup}
  187.                 fKeyGroups: TKeyGroup;                    {}
  188. {$ENDC}
  189. {$IFC UseTextGroup}
  190.                 fTextGroups: TTextGroup;                    {}
  191. {$ENDC}
  192. {$IFC UseRadioGroup}
  193.                 fRadioGroups: TRadioGroup;                {}
  194. {$ENDC}
  195. {$IFC UsePopUpMenu}
  196.                 fPopUpMenu: TPopUpMenu;                    {}
  197. {$ENDC}
  198. {$IFC UseListItem}
  199.                 fListItems: TListItem;                        {}
  200. {$ENDC}
  201.                 TextBoxRgn: RgnHandle;                        {region of all edit text items}
  202.                 iBeamHdl: CursHandle;                        {handle to the special cursor}
  203.                 wasDown: Boolean;                            {used to obscure cursor after a click in the text}
  204.             End;
  205.  
  206.     Var
  207.         HcurInfo: HDialogInfo;
  208.  
  209.         globalError: Integer;
  210.  
  211.  
  212.     Function DialogItemType (pItem: Integer): Integer;
  213.         Var
  214.             theType: Integer;
  215.             theHandle: handle;
  216.             theBox: Rect;
  217.     Begin
  218.         GetDItem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  219.         DialogItemType := theType;
  220.     End;        {DialogItemType}
  221.  
  222.     Procedure DialogClickButton (pItem: Integer);
  223.         Var
  224.             theType: Integer;
  225.             theHandle: handle;
  226.             theBox: Rect;
  227.             finalTicks: Longint;
  228.     Begin
  229.         GetDItem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  230.         If theType = btnCtrlItem Then
  231.             Begin
  232.                 HiliteControl(ControlHandle(theHandle), On);        {make it look}
  233.                 Delay(3, finalTicks);                                    {like the OK button was hit}
  234.                 HiliteControl(ControlHandle(theHandle), Off);
  235.             End
  236.         Else
  237.             globalError := DialogInvalidItem;
  238.     End;        {DialogClickButton}
  239.  
  240.     Procedure DialogClickEdit (pItem: Integer);
  241.     Begin
  242.         If DialogItemType(pItem) = editCtrlItem Then
  243.             SelIText(HcurInfo^^.curDialog, pItem, 0, 241)
  244.         Else
  245.             globalError := DialogInvalidItem;
  246.     End;        {DialogClickEdit}
  247.  
  248.     Procedure DialogClickRadioCheck (pItem: Integer);
  249.         Var
  250.             theType: Integer;
  251.             theHandle: handle;
  252.             theBox: Rect;
  253.     Begin
  254.         GetDItem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  255.         If (theType = chkCtrlItem) Or (theType = radCtrlItem) Then
  256.             SetCtlValue(ControlHandle(theHandle), BitXor(GetCtlValue(ControlHandle(theHandle)), On))
  257.         Else
  258.             globalError := DialogInvalidItem;
  259.     End;        {DialogClickRadioCheck}
  260.  
  261.     Function DialogFilter (theDialog: DialogPtr;
  262.                                     Var theEvent: EventRecord;
  263.                                     Var item: Integer): Boolean;
  264.  
  265.         Procedure DialogNullEvent;
  266.             Var
  267.                 mouseLoc: Point;
  268.         Begin
  269.             GetMouse(mouseLoc);
  270.             If PtInRgn(mouseLoc, HcurInfo^^.TextBoxRgn) Then
  271.                 SetCursor(HcurInfo^^.iBeamHdl^^)
  272.             Else
  273.                 SetCursor(arrow);
  274.         End;     {DialogNullEvent}
  275.  
  276.         Procedure DialogUpdate;
  277.             Var
  278.                 curPen: PenState;
  279.                 theType: Integer;
  280.                 theHandle: handle;
  281.                 theBox, titleBox: Rect;
  282.                 i: Integer;
  283.                 oldPort: GrafPtr;
  284.         Begin
  285.             GetPort(oldPort);
  286.             SetPort(theDialog);
  287.             GetPenState(curPen);
  288.             PenNormal;
  289.             PenSize(3, 3);
  290.             GetDItem(HcurInfo^^.curDialog, HcurInfo^^.btnDefault, theType, theHandle, theBox);
  291.             InsetRect(theBox, -4, -4);
  292.             FrameRoundRect(theBox, 16, 16);
  293.             PenSize(1, 1);
  294. {$IFC UseRadioGroup}
  295.             HcurInfo^^.fRadioGroups.DrawAll;
  296. {$ENDC}
  297. {$IFC UsePopUpMenu}
  298.             HcurInfo^^.fPopUpMenu.DrawAll;
  299. {$ENDC}
  300. {$IFC UseListItem}
  301.             HcurInfo^^.fListItems.DrawAll;
  302. {$ENDC}
  303.             SetPenState(curPen);
  304.             SetPort(oldPort);
  305.         End;    {DialogUpdate}
  306.  
  307.         Procedure DialogMouseDown (theEvent: EventRecord);
  308.         Begin
  309. {$IFC UseUserItem}
  310.             HcurInfo^^.fUserItems.Mouse(HcurInfo^^.curDialog, theEvent);
  311. {$ENDC}
  312. {$IFC UseListItem}
  313.             HcurInfo^^.fListItems.Mouse(HcurInfo^^.curDialog, theEvent);
  314. {$ENDC}
  315. {$IFC UsePopUpMenu}
  316.             HcurInfo^^.fPopUpMenu.Mouse(theEvent);
  317. {$ENDC}
  318.             GlobalToLocal(theEvent.where);                            {because PtInRect wants it that way}
  319.             If PtInRgn(theEvent.where, HcurInfo^^.TextBoxRgn) Then
  320.                 HcurInfo^^.wasDown := TRUE;                {if mouse down in text box}
  321.         End;     {DialogMouseDown}
  322.  
  323.         Procedure DialogKeyDown (theEvent: EventRecord);
  324.             Var
  325.                 i: Integer;
  326.                 chCode: Integer;
  327.                 ch: Char;
  328.                 cmdDown: Boolean;
  329.                 finalTicks: Longint;
  330.         Begin
  331.             With theEvent Do
  332.                 Begin
  333.                     chCode := BitAnd(message, CharCodeMask);
  334.                     ch := CHR(chCode);
  335.                     cmdDown := (BitAnd(modifiers, CmdKey) <> 0);
  336.                 End;
  337.             If chCode In [returnCode, enterCode] Then {user pressed Return or Enter}
  338.                 Begin
  339.                     DialogClickButton(HcurInfo^^.btnDefault);
  340.                     DialogFilter := TRUE;
  341.                     item := HcurInfo^^.btnDefault;
  342.                 End
  343.             Else If cmdDown Then
  344.                 Begin
  345.                     DialogFilter := TRUE;
  346.                     Case ch Of
  347.                         'x': 
  348.                             DlgCut(theDialog);
  349.                         'c': 
  350.                             DlgCopy(theDialog);
  351.                         'v': 
  352.                             DlgPaste(theDialog);
  353.                         'b': 
  354.                             DlgDelete(theDialog);
  355.                         Otherwise
  356.                             Begin
  357. {$IFC UseKeyGroup}
  358.                                 i := HcurInfo^^.fKeyGroups.Click(ch);
  359.                                 If i <> 0 Then
  360.                                     Begin
  361.                                         Case DialogItemtype(i) Of
  362.                                             btnCtrlItem: 
  363.                                                 item := i;                 {simulate user hitting button}
  364. {$IFC UseTextGroup}
  365.                                             chkCtrlItem: 
  366.                                                 HcurInfo^^.fTextGroups.Click(HcurInfo^^.curDialog, i);
  367. {$ELSEC}
  368.                                             chkCtrlItem: 
  369.                                                 DialogClickRadioCheck(i);
  370. {$ENDC}
  371. {$IFC UseRadioGroup}
  372.                                             radCtrlItem: 
  373.                                                 HcurInfo^^.fRadioGroups.Click(HcurInfo^^.curDialog, i);
  374. {$ELSEC}
  375.                                             radCtrlItem: 
  376.                                                 DialogClickRadioCheck(i);
  377. {$ENDC}
  378.                                             editText: 
  379.                                                 DialogClickEdit(i);
  380.                                             Otherwise
  381.                                         End;    {case}
  382.                                     End;        {IF}
  383. {$ENDC}
  384.                             End;        {Otherwise}
  385.                     End; {cmdDown}
  386.                 End; {case}
  387.         End;     {DialogKeyDown}
  388.  
  389.     Begin {DialogFilter}
  390.         item := 0;            {We return these two values.  Initialize them.}
  391.         DialogFilter := FALSE;
  392.  
  393.         If HcurInfo^^.wasDown And Not StillDown Then
  394.             Begin
  395.                 ObscureCursor;        {User clicked in editable text}
  396.                 HcurInfo^^.wasDown := FALSE;    {Reset "mouse down" flag}
  397.             End;
  398.         Case theEvent.what Of
  399.             nullEvent: 
  400.                 DialogNullEvent;
  401.             UpdateEvt: 
  402.                 DialogUpdate;
  403.             mouseDown: 
  404.                 DialogMouseDown(theEvent);
  405.             keyDown, autoKey: 
  406.                 DialogKeyDown(theEvent);
  407.             Otherwise
  408.         End;  {case theEvent.what}
  409.     End;     {function DialogFilter}
  410.  
  411.     Function DialogEvent: Integer;
  412.         Var
  413.             itemHit: Integer;             {item where event occurred - returned by ModalDialog}
  414.     Begin
  415.         ModalDialog(@DialogFilter, itemHit);             {calls DialogFilter for every event}
  416.         If itemHit <> 0 Then
  417.             Begin
  418.                 Case DialogItemType(itemHit) Of
  419.                     btnCtrlItem: 
  420.                         DialogClickButton(itemHit);
  421. {$IFC UseTextGroup}
  422.                     chkCtrlItem: 
  423.                         HcurInfo^^.fTextGroups.Click(HcurInfo^^.curDialog, itemHit);
  424. {$ELSEC}
  425.                     chkCtrlItem: 
  426.                         DialogClickRadioCheck(itemHit);
  427. {$ENDC}
  428. {$IFC UseRadioGroup}
  429.                     radCtrlItem: 
  430.                         HcurInfo^^.fRadioGroups.Click(HcurInfo^^.curDialog, itemHit);
  431. {$ELSEC}
  432.                     radCtrlItem: 
  433.                         DialogClickRadioCheck(itemHit);
  434. {$ENDC}
  435.                     Otherwise
  436.                 End; {case theType}
  437.             End;    {if item <> 0}
  438.         DialogEvent := itemHit;
  439.     End;     {DialogEvent}
  440.  
  441.  
  442. {}
  443. {-----------------------------------TDialog-----------------------------}
  444. {}
  445.     Procedure TDialog.Init;
  446.     Begin
  447.         globalError := DialogNoErr;
  448.         HcurInfo := HDialogInfo(NewHandle(SIzeOf(DialogInfo)));
  449.         HLock(Handle(HcurInfo));
  450.         Self.fPrivate := Handle(HcurInfo);
  451.         HcurInfo^^.number := 0;
  452.         HcurInfo^^.curDialog := Nil;
  453.         HcurInfo^^.numItems := 0;
  454.         HcurInfo^^.btnDefault := 0;
  455.         HcurInfo^^.chkDefault := [];
  456.         HcurInfo^^.textDefault := 0;
  457.         HcurInfo^^.iBeamHdl := Nil;
  458.         HcurInfo^^.wasDown := TRUE;
  459. {$IFC UseRadioGroup}
  460.         new(HcurInfo^^.fRadioGroups);
  461.         HcurInfo^^.fRadioGroups.Init;
  462. {$ENDC}
  463. {$IFC UsePopUpMenu}
  464.         new(HcurInfo^^.fPopUpMenu);
  465.         HcurInfo^^.fPopUpMenu.Init;
  466. {$ENDC}
  467. {$IFC UseTextGroup}
  468.         new(HcurInfo^^.fTextGroups);
  469.         HcurInfo^^.fTextGroups.Init;
  470. {$ENDC}
  471. {$IFC UseKeyGroup}
  472.         new(HcurInfo^^.fKeyGroups);
  473.         HcurInfo^^.fKeyGroups.Init;
  474. {$ENDC}
  475. {$IFC UseUserItem}
  476.         new(HcurInfo^^.fUserItems);
  477.         HcurInfo^^.fUserItems.Init;
  478. {$ENDC}
  479. {$IFC UseListItem}
  480.         new(HcurInfo^^.fListItems);
  481.         HcurInfo^^.fListItems.Init;
  482. {$ENDC}
  483.         Hunlock(Handle(HcurInfo));
  484.     End;        {TDialog.Init}
  485.  
  486.     Procedure TDialog.Define (pNumber: Integer;    {dialog number}
  487.                                     pChkDefault: DialogSet;                    {which check boxes default on}
  488.                                     pTextDefault: DialogNumber);            {which editText to put I-Beam}
  489.     Begin
  490.         globalError := DialogNoErr;
  491.         HcurInfo := HDialogInfo(Self.fPrivate);
  492.         HcurInfo^^.number := pNumber;
  493.         HcurInfo^^.chkDefault := pChkDefault;
  494.         HcurInfo^^.textDefault := pTextDefault;
  495.         HcurInfo^^.curDialog := GetNewDialog(HcurInfo^^.number, Nil, pointer(-1));
  496.     End;     {DialogInit}
  497.  
  498.     Procedure TDialog.Display (center: Boolean);
  499.         Const
  500.             noWrap = -1;
  501.  
  502.         Type
  503.             DialogItemPtr = ^DialogItem;
  504.             DialogItemHndl = ^DialogItemPtr;
  505.             DialogItem = Record
  506.                     numItems: Integer;        {relative to 0}
  507.                 End;
  508.  
  509.         Var
  510.             theDlogPeek: DialogPeek;
  511.             dHandle: DialogTHndl;
  512.             iHandle: DialogItemHndl;
  513.  
  514.         Procedure DialogDisplayTextItems;
  515.             Var
  516.                 i: Integer;
  517.                 theType: Integer;
  518.                 theHandle: Handle;
  519.                 theBox: Rect;
  520.         Begin
  521. {Set default check boxes and get bound of all editItems}
  522.             With HcurInfo^^ Do
  523.                 Begin
  524.                     TextBoxRgn := NewRgn;
  525.                     OpenRgn;
  526.                     For i := 1 To numItems Do
  527.                         Begin
  528.                             GetDItem(curDialog, i, theType, theHandle, theBox);
  529.                             If thetype = editCtrlItem Then
  530.                                 FrameRect(theBox);
  531. {$IFC UseTextGroup}
  532.                             If i In chkDefault Then
  533.                                 fTextGroups.Click(curDialog, i);
  534. {$ENDC}
  535.                         End;
  536.                     CloseRgn(TextBoxRgn);
  537.                     If textDefault <> 0 Then
  538.                         DialogClickEdit(textDefault);
  539.                 End;
  540.         End;    {DialogDisplayTextItems}
  541.  
  542.     Begin
  543.         globalError := DialogNoErr;
  544.         HcurInfo := HDialogInfo(Self.fPrivate);
  545.         HLock(Handle(HcurInfo));
  546.         With HcurInfo^^ Do
  547.             Begin
  548.                 iBeamHdl := GetCursor(iBeamCursor);
  549.                 wasDown := FALSE;
  550.                 FlushEvents(everyEvent, 0);
  551.                 theDlogPeek := DialogPeek(curDialog);
  552.                 btnDefault := theDlogPeek^.aDefItem;
  553.                 iHandle := DialogItemHndl(theDlogPeek^.items);
  554.                 numItems := iHandle^^.numItems;
  555.                 theDlogPeek^.textH^^.crOnly := noWrap;     {so we can turn off word wrap}
  556.                 If center Then
  557.                     Begin
  558.                         dHandle := DialogTHndl(GetResource('DLOG', number));
  559.                         Centered(dHandle^^.boundsRect, 2, 3);
  560.                         With dHandle^^.boundsRect Do
  561.                             MoveWindow(curDialog, left, top, TRUE);
  562.                     End;
  563.  
  564.                 DialogDisplayTextItems;
  565. {$IFC UseRadioGroup}
  566.                 fRadioGroups.Revise(curDialog);
  567. {$ENDC}
  568. {$IFC UsePopUpMenu}
  569.                 fPopUpMenu.Revise(curDialog);
  570. {$ENDC}
  571. {$IFC UseUserItem}
  572.                 fUserItems.Revise(curDialog);
  573. {$ENDC}
  574. {$IFC UseListItem}
  575.                 fListItems.Revise(curDialog);
  576. {$ENDC}
  577.                 SetPort(curDialog);                             {this makes later GlobalToLocal calls work right}
  578.                 ShowWindow(curDialog);                        {here I am!}
  579.                 InitCursor;                                        {we're ready, show an arrow}
  580.             End; {with}
  581.         Hunlock(Handle(HcurInfo));
  582.     End;     {TDialog.Display}
  583.  
  584.     Function TDialog.Accept: Integer;
  585.         Var
  586.             i: Integer;
  587.             theItem: Integer;
  588.             theType: Integer;
  589.             theHandle: handle;
  590.             theBox: Rect;
  591.     Begin
  592.         globalError := DialogNoErr;
  593.         HcurInfo := HDialogInfo(Self.fPrivate);
  594.         HLock(Handle(HcurInfo));
  595.         With HcurInfo^^ Do
  596.             Begin
  597.                 Repeat
  598.                     theItem := DialogEvent;
  599.                 Until DialogItemType(theItem) = btnCtrlItem;
  600.                 Accept := theItem;
  601.             End; {with}
  602.         Hunlock(Handle(HcurInfo));
  603.     End;     {DialogAccept}
  604.  
  605.     Function TDialog.Error: Integer;
  606.     Begin
  607.         Error := globalError;
  608.     End;        {TDialog.Error}
  609.  
  610.     Procedure TDialog.Free;
  611.     Begin
  612.         globalError := DialogNoErr;
  613.         HcurInfo := HDialogInfo(Self.fPrivate);
  614. {$IFC UsePopUpMenu}
  615.         HcurInfo^^.fPopUpMenu.Free;
  616. {$ENDC}
  617. {$IFC UseRadioGroup}
  618.         HcurInfo^^.fRadioGroups.Free;
  619. {$ENDC}
  620. {$IFC UseTextGroup}
  621.         HcurInfo^^.fTextGroups.Free;
  622. {$ENDC}
  623. {$IFC UseKeyGroup}
  624.         HcurInfo^^.fKeyGroups.Free;
  625. {$ENDC}
  626. {$IFC UseUserItem}
  627.         HcurInfo^^.fUserItems.Free;
  628. {$ENDC}
  629. {$IFC UseListItem}
  630.         HcurInfo^^.fListItems.Free;
  631. {$ENDC}
  632.         DisposeRgn(HcurInfo^^.TextBoxRgn);
  633.         DisposDialog(HcurInfo^^.curDialog);
  634.         DisposHandle(Handle(HcurInfo));
  635.         Inherited Free;
  636.     End;     {TDialog.Destroy}
  637.  
  638.     Procedure TDialog.RadioGroup (pOn: DialogNumber;    {which is initially on}
  639.                                     pBtns: DialogSet;                            {which btns in a single group}
  640.                                     pTitle: String;                            {if length > 0, then title with box}
  641.                                     pTitleTop: Boolean);                        {TRUE - title on top, FALSE - title at left end}
  642.         Var
  643.             i: Integer;
  644.             count: Integer;
  645.     Begin
  646. {$IFC UseRadioGroup}
  647.         HcurInfo := HDialogInfo(Self.fPrivate);
  648.         HcurInfo^^.fRadioGroups.Add(pOn, pBtns, pTitle, pTitleTop);
  649.         globalError := HcurInfo^^.fRadioGroups.Error;
  650. {$ELSEC}
  651.         globalError := DialogInvalidOp;
  652. {$ENDC}
  653.     End;     {TDialog.RadioGroup}
  654.  
  655.     Procedure TDialog.RadioGroupGet (pGroup: Integer;
  656.                                     Var pItem: Integer);
  657.     Begin
  658. {$IFC UseRadioGroup}
  659.         HcurInfo := HDialogInfo(Self.fPrivate);
  660.         HcurInfo^^.fRadioGroups.Get(pGroup, pItem);
  661.         globalError := HcurInfo^^.fRadioGroups.Error;
  662. {$ELSEC}
  663.         globalError := DialogInvalidOp;
  664. {$ENDC}
  665.     End;        {TDialog.RadioGroupGet}
  666.  
  667.     Procedure TDialog.RadioGroupSet (pGroup: Integer;
  668.                                     pItem: Integer);
  669.     Begin
  670. {$IFC UseRadioGroup}
  671.         HcurInfo := HDialogInfo(Self.fPrivate);
  672.         HcurInfo^^.fRadioGroups.Click(HcurInfo^^.curDialog, pItem);
  673.         globalError := HcurInfo^^.fRadioGroups.Error;
  674. {$ELSEC}
  675.         globalError := DialogInvalidOp;
  676. {$ENDC}
  677.     End;        {TDialog.RadioGroupSet}
  678.  
  679.     Procedure TDialog.TextGroup (pItem: DialogNumber;    {pairs of btn and edit text items}
  680.                                     pText: DialogNumber);
  681.     Begin
  682. {$IFC UseTextGroup}
  683.         HcurInfo := HDialogInfo(Self.fPrivate);
  684.         HcurInfo^^.fTextGroups.Add(pItem, pText);
  685.         globalError := HcurInfo^^.fTextGroups.Error;
  686. {$ELSEC}
  687.         globalError := DialogInvalidOp;
  688. {$ENDC}
  689.     End;     {DialogTextGroup}
  690.  
  691.     Procedure TDialog.PopMenu (pMenu: MenuHandle;        {}
  692.                                     pMenuRes: Integer;                                {}
  693.                                     pStatic: DialogNumber;                            {}
  694.                                     pInitiallyOn: Integer);                            {}
  695.     Begin
  696. {$IFC UsePopUpMenu}
  697.         HcurInfo := HDialogInfo(Self.fPrivate);
  698.         HcurInfo^^.fPopUpMenu.Add(pMenu, pMenuRes, pStatic, pInitiallyOn);
  699.         globalError := HcurInfo^^.fPopUpMenu.Error;
  700. {$ELSEC}
  701.         globalError := DialogInvalidOp;
  702. {$ENDC}
  703.     End;        {TDialog.PopMenu}
  704.  
  705.     Procedure TDialog.PopMenuGet (pGroup: Integer;
  706.                                     Var pItem: Integer;
  707.                                     Var pText: Str255);
  708.     Begin
  709. {$IFC UsePopUpMenu}
  710.         HcurInfo := HDialogInfo(Self.fPrivate);
  711.         HcurInfo^^.fPopUpMenu.Get(pGroup, pItem, pText);
  712.         globalError := HcurInfo^^.fPopUpMenu.Error;
  713. {$ELSEC}
  714.         globalError := DialogInvalidOp;
  715. {$ENDC}
  716.     End;        {TDialog.PopMenuGet}
  717.  
  718.     Procedure TDialog.PopMenuCallBack (pCallBack: ProcPtr);    {proc addr}
  719.     Begin
  720. {$IFC UsePopUpMenu}
  721.         HcurInfo := HDialogInfo(Self.fPrivate);
  722.         HcurInfo^^.fPopUpMenu.CallBack(pCallBack);
  723.         globalError := HcurInfo^^.fPopUpMenu.Error;
  724. {$ELSEC}
  725.         globalError := DialogInvalidOp;
  726. {$ENDC}
  727.     End;        {TDialog.PopMenuCallBack}
  728.  
  729.     Procedure TDialog.UserItems (pItem: DialogNumber;    {user item number}
  730.                                     pDraw, pEvent, pSelect: ProcPtr;                {}
  731.                                     pBox: Rect);                                        {Rect that contains the item}
  732.     Begin
  733. {$IFC UseUserItem}
  734.         HcurInfo := HDialogInfo(Self.fPrivate);
  735.         HcurInfo^^.fUserItems.Add(pItem, pDraw, pEvent, pSelect, pBox);
  736.         globalError := HcurInfo^^.fUserItems.Error;
  737. {$ELSEC}
  738.         globalError := DialogInvalidOp;
  739. {$ENDC}
  740.     End;     {TDialog.UserItem}
  741.  
  742.     Procedure TDialog.ItemList (pItem: DialogNumber;        {item number}
  743.                                     pInitiallyOn: Integer;                            {item initially selected}
  744.                                     pShown: Integer);                            {max items to show}
  745.     Begin
  746. {$IFC UseListItem}
  747.         HcurInfo := HDialogInfo(Self.fPrivate);
  748.         HcurInfo^^.fListItems.Add(pItem, pInitiallyOn, pShown);
  749.         globalError := HcurInfo^^.fListItems.Error;
  750. {$ELSEC}
  751.         globalError := DialogInvalidOp;
  752. {$ENDC}
  753.     End;        {TDialog.ItemList}
  754.  
  755.     Procedure TDialog.ItemListText (pText: Str255);
  756.     Begin
  757. {$IFC UseListItem}
  758.         HcurInfo := HDialogInfo(Self.fPrivate);
  759.         HcurInfo^^.fListItems.AddItem(pText);
  760.         globalError := HcurInfo^^.fListItems.Error;
  761. {$ELSEC}
  762.         globalError := DialogInvalidOp;
  763. {$ENDC}
  764.     End;        {TDialog.ItemListText}
  765.  
  766.     Procedure TDialog.ItemListGet (pGroup: Integer;
  767.                                     Var pItem: Integer;
  768.                                     Var pText: Str255);
  769.     Begin
  770. {$IFC UseListItem}
  771.         HcurInfo := HDialogInfo(Self.fPrivate);
  772.         HcurInfo^^.fListItems.Get(pGroup, pItem, pText);
  773.         globalError := HcurInfo^^.fListItems.Error;
  774. {$ELSEC}
  775.         globalError := DialogInvalidOp;
  776. {$ENDC}
  777.     End;        {TDialog.ItemListGet}
  778.  
  779.     Procedure TDialog.KeyButton (pKey: Char;        {command key}
  780.                                     pItem: DialogNumber);                    {button}
  781.     Begin
  782. {$IFC UseKeyGroup}
  783.         HcurInfo := HDialogInfo(Self.fPrivate);
  784.         HcurInfo^^.fKeyGroups.Add(pKey, pItem);
  785.         globalError := HcurInfo^^.fKeyGroups.Error;
  786. {$ELSEC}
  787.         globalError := DialogInvalidOp;
  788. {$ENDC}
  789.     End;     {TDialog.KeyButton}
  790.  
  791.     Function TDialog.GetBooleanValue (pItem: Integer): Boolean;
  792.         Var
  793.             theType: Integer;
  794.             theHandle: handle;
  795.             theBox: Rect;
  796.     Begin
  797.         globalError := DialogNoErr;
  798.         HcurInfo := HDialogInfo(Self.fPrivate);
  799.         GetDitem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  800.         If (theType = radCtrlItem) Or (theType = chkCtrlItem) Then
  801.             GetBooleanValue := (GetCtlValue(ControlHandle(theHandle)) = On)
  802.         Else
  803.             Begin
  804.                 globalError := DialogInvalidItem;
  805.                 GetBooleanValue := FALSE;
  806.             End;
  807.     End;    {TDialog.GetBooleanValue}
  808.  
  809.     Function TDialog.GetLongintValue (pItem: Integer): Longint;
  810.         Var
  811.             theType: Integer;
  812.             theHandle: handle;
  813.             theBox: Rect;
  814.             theText: Str255;
  815.             theValue: Longint;
  816.             isNum: Boolean;
  817.             i: Integer;
  818.             c: Char;
  819.     Begin
  820.         globalError := DialogNoErr;
  821.         HcurInfo := HDialogInfo(Self.fPrivate);
  822.         GetDItem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  823.         If (theType = editText) Or (theType = statText) Then
  824.             Begin
  825.                 GetIText(theHandle, theText);
  826.                 For i := 1 To Length(theText) Do
  827.                     Begin
  828.                         c := Copy(theText, i, 1);
  829.                         If i = 1 Then
  830.                             isNum := c In ['+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  831.                         Else
  832.                             isNum := isNum And (c In ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']);
  833.                     End;
  834.                 If isNum Then
  835.                     StringToNum(theText, theValue)
  836.                 Else
  837.                     Begin
  838.                         globalError := DialogNotNumber;
  839.                         theValue := 0;
  840.                     End;
  841.             End    {if Edit/Static Text item}
  842.         Else
  843.             Begin
  844.                 globalError := DialogNotNumber;
  845.                 theValue := 0;
  846.             End;
  847.         GetLongintValue := theValue;
  848.     End;        {TDialog.GetLongintValue}
  849.  
  850.     Function TDialog.GetStringValue (pItem: Integer): Str255;
  851.         Var
  852.             theType: Integer;
  853.             theHandle: handle;
  854.             theBox: Rect;
  855.             theText: Str255;
  856.     Begin
  857.         globalError := DialogNoErr;
  858.         HcurInfo := HDialogInfo(Self.fPrivate);
  859.         GetDItem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  860.         If (theType = editText) Or (theType = statText) Then
  861.             Begin
  862.                 GetIText(theHandle, theText);
  863.                 GetStringValue := theText;
  864.             End
  865.         Else
  866.             Begin
  867.                 globalError := DialogInvalidItem;
  868.                 GetStringValue := '';
  869.             End;
  870.     End;        {TDialog.GetStringValue}
  871.  
  872.     Procedure TDialog.SetBooleanValue (pItem: Integer;
  873.                                     theValue: Boolean);
  874.         Var
  875.             theType: Integer;
  876.             theHandle: handle;
  877.             theBox: Rect;
  878.     Begin
  879.         globalError := DialogNoErr;
  880.         HcurInfo := HDialogInfo(Self.fPrivate);
  881.         GetDItem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  882.         If (theType = radCtrlItem) Or (theType = chkCtrlItem) Then
  883.             If theValue Then
  884.                 SetCtlValue(ControlHandle(theHandle), On)
  885.             Else
  886.                 SetCtlValue(ControlHandle(theHandle), Off)
  887.         Else
  888.             globalError := DialogInvalidItem;
  889.     End;        {TDialog.SetBooleanValue}
  890.  
  891.     Procedure TDialog.SetLongintValue (pItem: Integer;
  892.                                     theValue: Longint);
  893.         Var
  894.             theType: Integer;
  895.             theHandle: handle;
  896.             theBox: Rect;
  897.             theText: Str255;
  898.     Begin
  899.         globalError := DialogNoErr;
  900.         HcurInfo := HDialogInfo(Self.fPrivate);
  901.         GetDItem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  902.         If (theType = editText) Or (theType = statText) Then
  903.             Begin
  904.                 NumToString(theValue, theText);
  905.                 SetIText(theHandle, theText);
  906.             End
  907.         Else
  908.             globalError := DialogInvalidItem;
  909.     End;        {TDialog.SetLongintValue}
  910.  
  911.     Procedure TDialog.SetStringValue (pItem: Integer;
  912.                                     theValue: Str255;
  913.                                     forceFit: Boolean);
  914.         Var
  915.             theType: Integer;
  916.             theHandle: handle;
  917.             theBox: Rect;
  918.             width, middle: Integer;
  919.             firstHalf, secondHalf: Str255;
  920.     Begin
  921.         globalError := DialogNoErr;
  922.         HcurInfo := HDialogInfo(Self.fPrivate);
  923.         GetDItem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  924.         If forceFit Then
  925.             Begin
  926.                 width := thebox.right - theBox.left;
  927.                 If (StringWidth(theValue) > width) Then
  928.                     Begin
  929.                         middle := Length(theValue) Div 2;
  930.                         firstHalf := Copy(theValue, 1, middle);
  931.                         secondHalf := Copy(theValue, middle + 1, 255);
  932.                         Repeat
  933.                             firstHalf := Copy(firstHalf, 1, Length(firstHalf) - 1);
  934.                             secondHalf := Copy(secondHalf, 2, Length(secondHalf) - 1);
  935.                             theValue := Concat(firstHalf, '╔', secondHalf);
  936.                         Until (StringWidth(theValue) < width);
  937.                     End;
  938.             End;    {if forceFit}
  939.         If (theType = editText) Or (theType = statText) Then
  940.             SetIText(theHandle, theValue)
  941.         Else
  942.             globalError := DialogInvalidItem;
  943.     End;        {TDialog.SetStringValue}
  944.  
  945.     Procedure TDialog.SelectText (pItem: Integer);
  946.     Begin
  947.         globalError := DialogNoErr;
  948.         HcurInfo := HDialogInfo(Self.fPrivate);
  949.         DialogClickEdit(pItem);
  950.     End;        {TDialog.SelectText}
  951.  
  952.     Procedure TDialog.CenterText (pItem: Integer);
  953.         Var
  954.             iText: Str255;
  955.             nilText: Str255;
  956.             theBox: Rect;
  957.             theType: Integer;
  958.             theHandle: Handle;
  959.     Begin
  960.         globalError := DialogNoErr;
  961.         HcurInfo := HDialogInfo(Self.fPrivate);
  962.         GetDItem(HcurInfo^^.curDialog, pItem, theType, theHandle, theBox);
  963.         If (theType = editText) Or (theType = statText) Then
  964.             Begin
  965.                 nilText := '';
  966.                 GetIText(theHandle, iText);
  967.                 SetIText(theHandle, nilText);
  968.                 TextBox(Ptr(Ord(@iText) + 1), Length(iText), theBox, teJustCenter);
  969.             End
  970.         Else
  971.             globalError := DialogInvalidItem;
  972.     End;     {TDialog.CenterText}
  973.  
  974. End.